/**
 * GeoSOA/util/Observable.js
 *
 * Observable object
 *
 * Generic implementation of the observer/observable pattern
 * 
 * Copyright (C) 2009 GeoSOA Research Group, Universite Laval
 * See LICENSE file under this distribution for licensing information
 * 
 * @author Etienne Dube
 * @since 20090813
 **/

dojo.provide("GeoSOA.util.Observable");

dojo.require("GeoSOA.util.ArrayList");

/**
 * The Observable object
 * 
 * @constructor
 */
GeoSOA.util.Observable = function (subject) {
	this._observers = new GeoSOA.util.ArrayList();
	this._subject = subject;
};

/**
 * Registers an observer function
 *
 * @param {Function} func Function to call to notify observer (optionally
 * takes an object as 1st argument)
 */
GeoSOA.util.Observable.prototype.register = function (func) {
	this._observers.add(func);
};

/**
 * Unregisters an observer function
 * 
 * @param {Function} func Observer function to remove. This must be same
 * instance of the function that was first registered with register(),
 * hence it may be useful to keep a reference to this function in the
 * client module.
 * 
 * @param {Function} func Function to remove from the observers list
 * @return true if the function was found and unregistered, otherwise false
 * @type Boolean
 */
GeoSOA.util.Observable.prototype.unregister = function (func) {
	var idx = this._observers.indexOf(func);
	if (idx != -1) {
		this._observers.removeAt(idx);
		return true;
	}
	return false;
};

/**
 * Notify all observers of an update to this object. The subject object
 * is passed as an argument to the function
 */
GeoSOA.util.Observable.prototype.update = function () {
	var i;
	for (i = 0 ; i < this._observers.count() ; i++) {
		(this._observers.getAt(i))(this._subject);
	}
};

/**
 * Sets the subject object that is passed to every registered observer
 * when calling update()
 *
 * @param {Function} subject The subject object
 */
GeoSOA.util.Observable.prototype.setSubject = function (subject) {
	this._subject = subject;
};

/**
 * Returns the subject object
 *
 * @return The subject object
 */

GeoSOA.util.Observable.prototype.getSubject = function () {
	return this._subject;
};
